﻿using Engine;
using Game.NetWork.Packages;
using Game.NetWork;
using Game.Server.Event;
using Game.Server.PlayerEvent;
using System.Text;

namespace Game.Server.Plugins
{
    public class WhistleInfoGetZHPlugin : ServerPlugin, IPlayerInteractEventHandle
    {
        public override int Version => 10000;

        public override string Name => "哨子获取信息插件";

        public byte FirstLevel => 0;

        public override void Initialize()
        {
            PlayerInteractEventManager.AddObject(this);
        }

        public bool Use(ComponentPlayer componentPlayer, object raycast, int activeBlockValue)
        {
            int blockId = Terrain.ExtractContents(activeBlockValue);
            if (blockId == 160 && componentPlayer.PlayerData.ServerManager)
            {
                SubsystemTerrain subsystemTerrain = componentPlayer.Project.FindSubsystem<SubsystemTerrain>();
                SubsystemPickables subsystemPickables = componentPlayer.Project.FindSubsystem<SubsystemPickables>();
                SubsystemPlayers subsystemPlayers = componentPlayer.Project.FindSubsystem<SubsystemPlayers>();
                if (raycast is TerrainRaycastResult)
                {
                    CellFace cellFace = ((TerrainRaycastResult)raycast).CellFace;
                    try
                    {
                        ClipboardManager.ClipboardString = $"{cellFace.X} {cellFace.Y} {cellFace.Z}";
                    }
                    catch
                    {
                    }
                    int cellValue = subsystemTerrain.Terrain.GetCellValue(cellFace.X, cellFace.Y, cellFace.Z);
                    int limitValue = Terrain.ReplaceLight(cellValue, 0);
                    int id = Terrain.ExtractContents(cellValue);
                    int data = Terrain.ExtractData(cellValue);
                    int dropsValue = -1;
                    foreach (Pickable pickable in subsystemPickables.Pickables)
                    {
                        float distance = Vector3.Distance(pickable.Position, new Vector3(cellFace.Point));
                        if (distance <= 1.5f)
                        {
                            dropsValue = pickable.Value;
                            break;
                        }
                    }
                    string blockDebug = string.Empty;
                    string furnitureDebug = string.Empty;
                    string dropsDebug = string.Empty;
                    string territoryDebug = string.Empty;
                    blockDebug = string.Format("方块ID:{0}；特殊值:{1}；方块值:{2}\n标准坐标:({3},{4},{5})；方块面:{6}", id, data, limitValue, cellFace.X, cellFace.Y, cellFace.Z, cellFace.Face);
                    if (id == 227)
                    {
                        int furnitureIndex = FurnitureBlock.GetDesignIndex(data);
                        int furnitureRotation = FurnitureBlock.GetRotation(data);
                        int furnitureFace = ((cellFace.Face - furnitureRotation) >= 0) ? (cellFace.Face - furnitureRotation) : (cellFace.Face - furnitureRotation + 4);
                        if (cellFace.Face == 4 || cellFace.Face == 5)
                        {
                            furnitureFace = cellFace.Face;
                        }
                        furnitureDebug = string.Format("\n家具序号:{0}；家具面:{1}", furnitureIndex, furnitureFace);
                    }
                    if (dropsValue != -1)
                    {
                        int dropsId = Terrain.ExtractContents(dropsValue);
                        int dropsData = Terrain.ExtractData(dropsValue);
                        dropsDebug = string.Format("\n检测到掉落物的ID:{0}；特殊值:{1}；方块值:{2}", dropsId, dropsData, dropsValue);
                        if (dropsId == 203)
                        {
                            int clothId = ClothingBlock.GetClothingIndex(dropsData);
                            dropsDebug += "；衣物序号:" + clothId;
                        }
                    }
                    if(SubsystemBedrockBlockBehavior.CheckIsInTerritoriy(cellFace.X, cellFace.Z, out Territoriy territoriy))
                    {
                        PlayerData playerData = subsystemPlayers.PlayersData.Find(p => { return p.PlayerGUID == territoriy.OwnerGuid; });
                        if(playerData != null)
                        {
                            territoryDebug += "\n该领地主人为:" + playerData.Name + " 社区ID:" + playerData.Client.CommunityAccountId;
                        }
                    }
                    DisplaySmallMessageNet(componentPlayer, blockDebug + furnitureDebug + dropsDebug + territoryDebug);
                }
                else if (raycast is BodyRaycastResult)
                {
                    ComponentBody componentBody = ((BodyRaycastResult)raycast).ComponentBody;
                    if (componentBody != null)
                    {
                        string keyName = componentBody.Entity.ValuesDictionary.DatabaseObject.Name;
                        try
                        {
                            ClipboardManager.ClipboardString = keyName;
                        }
                        catch
                        {
                        }
                        ComponentCreature componentCreature = componentBody.Entity.FindComponent<ComponentCreature>();
                        ComponentDamage componentDamage = componentBody.Entity.FindComponent<ComponentDamage>();
                        string entityDebug = "生物实体名:" + keyName;
                        Point3 bodyPos = new Point3((int)MathUtils.Floor(componentBody.Position.X), (int)MathUtils.Floor(componentBody.Position.Y), (int)MathUtils.Floor(componentBody.Position.Z));
                        if (componentCreature != null)
                        {
                            string displayName = componentCreature.DisplayName;
                            float health = componentCreature.ComponentHealth.Health * 100;
                            string mass = componentBody.Mass.ToString();
                            string boxSize = componentBody.BoxSize.ToString();
                            float flySpeed = componentCreature.ComponentLocomotion.FlySpeed;
                            float walkSpeed = componentCreature.ComponentLocomotion.WalkSpeed;
                            float jumpSpeed = componentCreature.ComponentLocomotion.JumpSpeed;
                            componentCreature.ComponentLocomotion.SwimSpeed.ToString();
                            entityDebug += string.Format("；名称:{0}；\n血量:{1}%；质量:{2}；\n位置:({3})；碰撞箱:{4}；", displayName, health, mass, bodyPos.ToString(), boxSize);
                            entityDebug += string.Format("\n飞行速度:{0}；行走速度:{1}；跳跃速度:{2}", MathUtils.Round(flySpeed * 10f) / 10f, MathUtils.Round(walkSpeed * 10f) / 10f, MathUtils.Round(jumpSpeed * 10f) / 10f);
                        }
                        else if (componentDamage != null)
                        {
                            float hitPoint = componentDamage.Hitpoints * 100;
                            float attackRes = componentDamage.AttackResilience;
                            string mass = componentBody.Mass.ToString();
                            string boxSize = componentBody.BoxSize.ToString();
                            entityDebug += string.Format("；血量:{0}%；\n攻击抗性:{1}；质量:{2}；\n位置:({3})；碰撞箱:{4}；", hitPoint, attackRes, mass, bodyPos.ToString(), boxSize);
                        }
                        DisplaySmallMessageNet(componentPlayer, entityDebug);
                    }
                }
                else if (raycast is MovingBlocksRaycastResult)
                {
                    IMovingBlockSet movingBlockSet = ((MovingBlocksRaycastResult)raycast).MovingBlockSet;
                    string moveDebug = (movingBlockSet.Tag != null) ? "该运动方块标签名为:" + movingBlockSet.Tag.ToString() : "该运动方块标签名不存在";
                    moveDebug += "；所在位置:" + string.Format("({0})", movingBlockSet.Position.ToString());
                    DisplaySmallMessageNet(componentPlayer, moveDebug);
                }
                else
                {
                    ComponentBody playerBody = componentPlayer.ComponentBody;
                    Point3 playerPos = new Point3((int)MathUtils.Floor(playerBody.Position.X), (int)MathUtils.Floor(playerBody.Position.Y), (int)MathUtils.Floor(playerBody.Position.Z));
                    try
                    {
                        ClipboardManager.ClipboardString = $"{playerPos.X} {playerPos.Y} {playerPos.Z}";
                    }
                    catch
                    {
                    }
                    DisplaySmallMessageNet(componentPlayer, string.Format("玩家名:[社区ID{0}]{1}; 玩家坐标:({2})", componentPlayer.PlayerData.Client.CommunityAccountId, componentPlayer.PlayerData.Name, playerPos.ToString()));
                }
            }
            return true;
        }

        public bool Interact(ComponentPlayer componentPlayer, CellFace cellFace)
        {
            return true;
        }

        public bool Hit(ComponentPlayer componentPlayer, ComponentBody componentBody, Vector3 hitPoint, Vector3 hitDirection)
        {
            return true;
        }

        public bool Aim(ComponentPlayer componentPlayer, int activeBlockValue, Ray3 aim, AimState state)
        {
            return true;
        }

        public override void Load()
        {
        }

        public override void Save()
        {
        }

        /// <summary>
        /// 给指定玩家发送提示
        /// </summary>
        /// <param name="componentPlayer"></param>
        /// <param name="text"></param>
        public void DisplaySmallMessageNet(ComponentPlayer componentPlayer, string text)
        {
            var messagePackget = new MessagePackage(null, text, 0, null);
            messagePackget.To = componentPlayer.PlayerData.Client;
            CommonLib.Net.QueuePackage(messagePackget);
        }
    }
}